package com.example.waypoint;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.w3c.dom.NodeList;

import utility.MyOverlays;

import com.google.android.maps.*;

import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;



public class RutaActivity extends MapActivity {
	private static int RUTA_PISCINA = 1;
	private static int RUTA_ACACIAS = 2;
	private static int RUTA_TERMINAL = 3;
	private static double LAT_CENTRO=-2.144891*1E6;
	private static double LNG_CENTRO=-79.965448*1E6;
	private MyOverlays itemizedoverlay;
	
	GeoPoint point = new GeoPoint((int)LAT_CENTRO,(int)LNG_CENTRO);
	GeoPoint point_piscina = new GeoPoint((int)LAT_CENTRO,(int)LNG_CENTRO);
	GeoPoint point_acacias = new GeoPoint((int)LAT_CENTRO,(int)LNG_CENTRO);
	GeoPoint point_terminal = new GeoPoint((int)LAT_CENTRO,(int)LNG_CENTRO);
	
	
	LinearLayout linearLayout;
	MapView mapView;
	ImageButton imageButtomHome;
	LocationManager locationManager; 
	MapController mapController;
	Button rutaTerminalButton;
    Button rutaPiscinaButton;
    Button rutaAcaciasButton;
    Button rutaSurButton;
	Button homeButton;
	ImageView logo;


	/****************** Listas para dibujar la ruta**********************/
	ArrayList<GeoPoint> all_geo_points_piscina;
	ArrayList<GeoPoint> all_geo_points_acacias;
	ArrayList<MiPunto> lista_guia_piscina;
		
	ArrayList<MiPunto> lista_guia_acacias;
	ArrayList<GeoPoint> all_geo_points_terminal;
	ArrayList<MiPunto> lista_guia_terminal;
	/********************************************************************/
	Helper helper ;
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_ruta);
        inicializarBotones();
        agregarEventos();
        helper = new Helper();
        
        all_geo_points_piscina = new ArrayList<GeoPoint>();
        all_geo_points_acacias = new ArrayList<GeoPoint>();
        all_geo_points_terminal = new ArrayList<GeoPoint>();
        
        lista_guia_piscina = helper.getRuta(RUTA_PISCINA);
        lista_guia_acacias = helper.getRuta(RUTA_ACACIAS);
        lista_guia_terminal = helper.getRuta(RUTA_TERMINAL);
        Log.i("Puntos de terminal", Integer.toString(lista_guia_terminal.size()));
        
        mapView = (MapView)findViewById(R.id.mapviewruta);
        mapView.setBuiltInZoomControls(true);
        mapController = mapView.getController();
        mapController.setZoom(14);
        mapController.setCenter(point);
        cagarPuntosRuta();
        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        mapController.setCenter(point);
        mapView.postInvalidate();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_maps, menu);
        return true;
    }
    
    public class GeoUpdateHandler implements LocationListener {

		public void onLocationChanged(Location location) {
		
				int lat = (int) (location.getLatitude() * 1E6);
				int lng = (int) (location.getLongitude() * 1E6);
				
				GeoPoint point = new GeoPoint(lat, lng);
				createMarker();
				mapController.setZoom(16);
				mapController.setCenter(point);
		}

		public void onProviderDisabled(String provider) {
		}

		public void onProviderEnabled(String provider) {
		}

		public void onStatusChanged(String provider, int status, Bundle extras) {
		}
	}

	@Override
	protected boolean isRouteDisplayed() {
		// TODO Auto-generated method stub
		return false;
	}
	
	private void createMarker() {
		GeoPoint p = mapView.getMapCenter();
		OverlayItem overlayitem = new OverlayItem(p, "", "");
		itemizedoverlay.addOverlay(overlayitem);
		mapView.getOverlays().add(itemizedoverlay);
	}
	
    
    private void inicializarBotones(){
		rutaTerminalButton = (Button)findViewById(R.id.rutaTerminal);
		rutaPiscinaButton = (Button)findViewById(R.id.rutaPiscina);
		rutaAcaciasButton = (Button)findViewById(R.id.rutaAcacias);
		logo = (ImageView)findViewById(R.id.logo);
	}
	
	private void agregarEventos(){
		rutaTerminalButton.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				mapView.getOverlays().clear();
				Log.i("Puntos de terminal", Integer.toString(all_geo_points_terminal.size()));
				mapView.getOverlays().add(new MyOverlay(all_geo_points_terminal));
				mapView.postInvalidate();
			}
		});
		
		rutaPiscinaButton.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				mapView.getOverlays().clear();
				mapView.getOverlays().add(new MyOverlay(all_geo_points_piscina));
				mapView.postInvalidate();
			}
		});
		
		rutaAcaciasButton.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				mapView.getOverlays().clear();
				
			}
		});
		
		logo.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				
			}
		});
	}
	
	private void cagarPuntosRuta(){
		dibujarRuta(lista_guia_piscina,all_geo_points_piscina);
		dibujarRuta(lista_guia_acacias,all_geo_points_acacias);
		dibujarRuta(lista_guia_terminal,all_geo_points_terminal);
	}
	
	public void dibujarRuta(ArrayList<MiPunto> lista_guia, ArrayList<GeoPoint> all_geo_points){
		MiPunto actual;
		MiPunto siguiente;
		
		if(all_geo_points.size()==0){
			for(int i=0; i<lista_guia.size()-1; i++){
				actual = lista_guia.get(i);
				siguiente = lista_guia.get(i+1);
		        if(siguiente.getLatitud() == 0.0 || actual.getLatitud()==0){
		        	i++;
		        }else{
		        	getDirections(actual.getLatitud(),actual.getLongitud(),siguiente.getLatitud(),siguiente.getLongitud(),all_geo_points);
		        }
			}
		}
	}
	
	public  void getDirections(double lat1, double lon1, double lat2, double lon2, ArrayList<GeoPoint> all_geo_points) {
	
        String url = "http://maps.googleapis.com/maps/api/directions/xml?&origin="+lat1+","+lon1+"&destination="+lat2+","+lon2+"&sensor=true&units=metric";
        String tag[] = { "lat", "lng","points" };
       
        HttpResponse response = null;
        try {
            HttpClient httpClient = new DefaultHttpClient();
            HttpContext localContext = new BasicHttpContext();
            HttpPost httpPost = new HttpPost(url);
            response = httpClient.execute(httpPost, localContext);
            InputStream in = response.getEntity().getContent();
            DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
            org.w3c.dom.Document doc = builder.parse(in);
            if (doc != null) {
                NodeList nl3;
            	nl3 = doc.getElementsByTagName(tag[2]);
            	/*nl1 = doc.getElementsByTagName(tag[0]);
                nl2 = doc.getElementsByTagName(tag[1]);
                
                if (nl1.getLength() > 0) {
                    for (int i = 0; i < nl1.getLength(); i++) {
                        org.w3c.dom.Node node1 = nl1.item(i);
                        org.w3c.dom.Node node2 = nl2.item(i);
                        double lat = Double.parseDouble(node1.getTextContent());
                        double lng = Double.parseDouble(node2.getTextContent());
                        //all_geo_points.add(new GeoPoint((int) (lat * 1E6), (int) (lng * 1E6)));		
                    }
                } else {
                    // No points found
                }*/
                if(nl3.getLength()>0){
                	Log.i("Cargando puntos:",Integer.toString(nl3.getLength()));
                	for (int i = 0; i < nl3.getLength()-1; i++) {
                        org.w3c.dom.Node node3 = nl3.item(i);
                        String encode = (node3.getTextContent());
                        decodePoly(encode,all_geo_points);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
	}
	
	private void decodePoly(String encoded, List<GeoPoint> poly) {
		  int index = 0, len = encoded.length();
		  int lat = 0, lng = 0;

		  while (index < len) {
		      int b, shift = 0, result = 0;
		      do {
		          b = encoded.charAt(index++) - 63;
		          result |= (b & 0x1f) << shift;
		          shift += 5;
		      } while (b >= 0x20);
		      int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
		      lat += dlat;

		      shift = 0;
		      result = 0;
		      do {
		          b = encoded.charAt(index++) - 63;
		          result |= (b & 0x1f) << shift;
		          shift += 5;
		      } while (b >= 0x20);
		      int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
		      lng += dlng;

		      GeoPoint p = new GeoPoint((int) (((double) lat / 1E5) * 1E6),
		           (int) (((double) lng / 1E5) * 1E6));
		      poly.add(p);
		  }
		}
}
